﻿
using System.Collections.ObjectModel;
using System.Windows.Input;
using DebIt.Common.Model;

namespace DebIt.ViewModel
{
    public class LoanEditViewModel : ViewModelBase
    {
        #region variables

        private const int MaxLoanItems = 30;
        private Loan _loan;
        private ObservableCollection<Client> _clients = new ObservableCollection<Client>();

        #endregion


        #region constructor

        public LoanEditViewModel(int id)
        {
            Loan = id == 0 ? Service.NewLoan() : Service.GetLoan(id);
            foreach(var li in Loan.LoanItems)
                li.PropertyChanged += LiPropertyChanged;
        }

        ~LoanEditViewModel()
        {
            foreach (var li in Loan.LoanItems)
                li.PropertyChanged -= LiPropertyChanged;
        }

        #endregion


        #region properties

        public Loan Loan
        {
            get { return _loan; }
            set
            {
                if (_loan == value) return;
                SendPropertyChanging(() => Loan);
                _loan = value;
                SendPropertyChanged(() => Loan);
            }
        }

        public ObservableCollection<Client> Clients
        {
            get { return _clients; }
            set
            {
                if (_clients == value) return;
                SendPropertyChanging(() => Clients);
                _clients = value;
                SendPropertyChanged(() => Clients);
            }
        }

        #endregion


        #region method

        protected override void Load()
        {
            Service.GetAllClients().ForEach(x => Clients.Add(x));
        }

        public void Save()
        {
            Service.Update(Loan);
            foreach (var li in Loan.LoanItems)
            {
                Service.Update(li);
            }
        }

        static void LiPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            Service.Update((LoanItem)sender);
        }

        #endregion


        #region commands
        
        #region add client comamnd

        private ICommand _addClientCommand;

        public ICommand AddClientCommand
        {
            get
            {
                return _addClientCommand ?? (_addClientCommand = new PhoneCommand<Client>(
                                                                     AddClient,
                                                                     CanAddClient
                                                                     ));
            }
        }

        private void AddClient(Client client)
        {
            if (client != null)
            Service.NewClientLoanStateFor(Loan, client);
        }

        private bool CanAddClient(Client parameter)
        {
            return true;
        }

        #endregion

        #region remove client comamnd

        private ICommand _removeClientCommand;

        public ICommand RemoveClientCommand
        {
            get
            {
                return _removeClientCommand ?? (_removeClientCommand = new PhoneCommand<ClientLoanState>(
                                                                     RemoveClientCommandClient,
                                                                     CanRemoveClient
                                                                     ));
            }
        }

        private void RemoveClientCommandClient(ClientLoanState clientLoanState)
        {
            Service.Delete(clientLoanState);
        }

        private bool CanRemoveClient(ClientLoanState clientLoanState)
        {
            return true;
        }

        #endregion

        #region add loan item comamnd

        private ICommand _addLoanItemCommand;

        public ICommand AddLoanItemCommand
        {
            get
            {
                return _addLoanItemCommand ?? (_addLoanItemCommand = new PhoneCommand<Loan>(
                                                                     AddLoanItem,
                                                                     CanAddLoanItem
                                                                     ));
            }
        }

        private void AddLoanItem(Loan loan)
        {
            Service.NewLoanItemFor(loan).PropertyChanged += LiPropertyChanged;
        }

        private bool CanAddLoanItem(Loan parameter)
        {
            return Loan.LoanItems.Count< MaxLoanItems;
        }

        #endregion

        #region remove loan item comamnd

        private ICommand _removeLoanItemCommand;

        public ICommand RemoveLoanItemCommand
        {
            get
            {
                return _removeLoanItemCommand ?? (_removeLoanItemCommand = new PhoneCommand<LoanItem>(
                                                                     RemoveLoanItem,
                                                                     CanRemoveLoanItem
                                                                     ));
            }
        }

        private void RemoveLoanItem(LoanItem loanItem)
        {
            loanItem.PropertyChanged -= LiPropertyChanged;
            Service.Delete(loanItem);
        }

        private bool CanRemoveLoanItem(LoanItem loanItem)
        {
            return true;
        }

        #endregion

        #endregion
    }
}
